﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;

namespace BrowserCollect
{
    internal static class MemoryAnalyzer
    {
        private static long ApplicationMemoryUsage;
        private static long TotalMemory;
        private static long AvailableMemory;
        private static int _funcInvoked = 0;
        static MemoryAnalyzer()
        {
            MEMORYSTATUSEX memStatus = new MEMORYSTATUSEX();
            if (GlobalMemoryStatusEx(memStatus))
            {
                TotalMemory = (long)memStatus.ullTotalPhys;
                AvailableMemory = (long)memStatus.ullAvailPhys;
            }
        }

        public static bool NeedRestart()
        {
            // 调用100次重启playwright
            if (_funcInvoked++ >= 100)
            {
                _funcInvoked = 0;
                return true;
            }

            // 每5次检查一次内存
            if (_funcInvoked % 5  == 0)
            {
                ApplicationMemoryUsage = System.Environment.WorkingSet;
                // 占用内存超过2G重启
                if (ApplicationMemoryUsage / 1024 / 1024 / 1024 >= 2)
                    return true;

                var memStatus = new MEMORYSTATUSEX();
                if (GlobalMemoryStatusEx(memStatus))
                {
                    TotalMemory = (long)memStatus.ullTotalPhys;
                    AvailableMemory = (long)memStatus.ullAvailPhys;
                }
                // 系统内存占用剩余10%重启
                if (TotalMemory > 0 && AvailableMemory / (decimal)TotalMemory <= 0.1m)
                    return true;
            }


            return false;
        }


        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
        private class MEMORYSTATUSEX
        {
            public uint dwLength;
            public uint dwMemoryLoad;
            public ulong ullTotalPhys;
            public ulong ullAvailPhys;
            public ulong ullTotalPageFile;
            public ulong ullAvailPageFile;
            public ulong ullTotalVirtual;
            public ulong ullAvailVirtual;
            public ulong ullAvailExtendedVirtual;
            public MEMORYSTATUSEX()
            {
                this.dwLength = (uint)Marshal.SizeOf(typeof(MEMORYSTATUSEX));
            }
        }


        [return: MarshalAs(UnmanagedType.Bool)]
        [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        static extern bool GlobalMemoryStatusEx([In, Out] MEMORYSTATUSEX lpBuffer);
    }
}
